package com.ac.scum.log.task.face.log.counsumer.stages;

import com.ac.common.core.id.SnowflakeIdGenerator;
import com.ac.scum.log.bean.Player;
import com.ac.scum.log.bean.ServerFTPLogViolation;
import com.ac.scum.log.task.face.log.counsumer.LogConsumer;
import com.ac.scum.log.task.mapper.log.ServerFTPLogViolationMapper;
import com.ac.scum.log.task.utils.queue.FTPQueueItem;
import com.google.common.collect.Lists;
import io.micrometer.common.util.StringUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
@AllArgsConstructor
public class ViolationsLogConsumer implements LogConsumer {
    private final SnowflakeIdGenerator snowflakeIdGenerator;
    private final ServerFTPLogViolationMapper serverFTPLogViolationMapper;
    private static final Map<String, String> ACTION_CN_NAMES = new HashMap<>();

    static {
        ACTION_CN_NAMES.put("PrisonerActionIgniteItem", "点燃物品");
        ACTION_CN_NAMES.put("PrisonerActionEatItem", "吃东西");
        ACTION_CN_NAMES.put("PrisonerVehicleAction_OpenOrCloseDoor", "打开或关闭车门");
        ACTION_CN_NAMES.put("PrisonerActionRemoveItemFromHands", "从手中移除物品");
        ACTION_CN_NAMES.put("PrisonerActionChangeVehicleWeaponAimingStance", "改变车辆武器瞄准姿态");
        ACTION_CN_NAMES.put("PrisonerActionTakeItemInHands", "将物品拿到手中");
        ACTION_CN_NAMES.put("PrisonerActionChangeWeaponFiringMode", "切换武器射击模式");
        ACTION_CN_NAMES.put("PrisonerActionCheckWeaponFiringMode", "检查武器射击模式");
        ACTION_CN_NAMES.put("PrisonerVehicleAction_SwitchMountSlot", "切换载具挂载槽");
        ACTION_CN_NAMES.put("PrisonerActionLoadAmmoIntoMagazine", "将弹药装入弹夹");
        ACTION_CN_NAMES.put("PrisonerActionReloadWeapon", "武器重新装填弹药");
        ACTION_CN_NAMES.put("PrisonerActionOpenItem", "打开一个物品/容器");
        ACTION_CN_NAMES.put("PrisonerActionCheckWeaponAmmo", "检查武器弹药");
        ACTION_CN_NAMES.put("PrisonerVehicleAction_ForceUnmount", "载具摧毁或其他原因，强制从载具中移除玩家");
        ACTION_CN_NAMES.put("PrisonerVehicleAction_Unmount", "载具摧毁或其他原因，从载具中移除玩家");
        ACTION_CN_NAMES.put("PrisonerActionForceUnlock", "强制解锁");
        ACTION_CN_NAMES.put("PrisonerActionMinigame", "小游戏（开锁，剪线，破解读卡器等）");
        ACTION_CN_NAMES.put("PrisonerActionThrowItem", "投掷物品");
        ACTION_CN_NAMES.put("PrisonerActionDestroyItem", "销毁物品");
        ACTION_CN_NAMES.put("PrisonerActionSearchObject", "搜索物品");
        ACTION_CN_NAMES.put("PrisonerActionChopBaseElement", "摧毁基地元素");
        ACTION_CN_NAMES.put("PrisonerVehicleAction_Mount", "乘坐/驾驶载具");
        ACTION_CN_NAMES.put("PrisonerActionStartResting", "开始休息");
        ACTION_CN_NAMES.put("PrisonerActionRepairItem", "修复物品");
        ACTION_CN_NAMES.put("PrisonerActionAddWeaponAttachment", "添加武器配件");
        ACTION_CN_NAMES.put("PrisonerActionStopResting", "停止休息");
        ACTION_CN_NAMES.put("PrisonerActionGesture", "做出手势");
        ACTION_CN_NAMES.put("PrisonerActionCraftItem", "制作物品");
        ACTION_CN_NAMES.put("PrisonerActionInjectSubstance", "扎针");
        ACTION_CN_NAMES.put("PrisonerActionDefecate", "拉屎");
        ACTION_CN_NAMES.put("PrisonerActionCutObject", "切割物品");
        ACTION_CN_NAMES.put("PrisonerActionWhistle", "吹口哨");
        ACTION_CN_NAMES.put("PrisonerActionInsertArrow", "装填箭矢");
        ACTION_CN_NAMES.put("PrisonerActionExecuteBodyConditionInteraction", "身体状态交互（治疗）");
        ACTION_CN_NAMES.put("AmmoCountMismatch", "弹药数量不匹配");
        ACTION_CN_NAMES.put("MeeleDamageLocationsMismatch", "近战伤害位置不匹配");
        ACTION_CN_NAMES.put("ProjectileDamageLocationsMismatch", "抛射物伤害位置不匹配");
        ACTION_CN_NAMES.put("MeleeDamageToBBElementLocationMismatch", "近战伤害对基地元素的位置不匹配");
        ACTION_CN_NAMES.put("OutOfInteractionRange", "超出交互范围");
        ACTION_CN_NAMES.put("OutOfInteractionRange2", "超出交互范围");
        ACTION_CN_NAMES.put("NoPermissionToAccessInventory", "没有权限访问物品容器");
    }

    @Override
    public void consumerLog(FTPQueueItem ftpQueueItem) {
        try {
            writeAllPlayerInfoInCache(ftpQueueItem);
            Pattern aConZGameModeKickPlayerPattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): AConZGameMode::KickPlayer: User id: '(\\d+)', Reason: (.+)");
            Pattern banByUserId = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): AConZGameMode::BanPlayerById: User id: '(\\d+)'");
            Pattern requestCharacterActionViolationDetectedPattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): Request character action violation detected -> User: (.+?) \\((\\d+), (\\d+)\\), Desc: (.+?), Action: (.+?), Server location: X=(-?\\d+\\.\\d+) Y=(-?\\d+\\.\\d+) Z=(-?\\d+\\.\\d+), Client location: X=(-?\\d+\\.\\d+) Y=(-?\\d+\\.\\d+) Z=(-?\\d+\\.\\d+), Distance: ([\\d.]+) m");
            Pattern outOfInteractionRangePattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): Equip clothes item violation detected -> (.+?), User: (.+?) \\((\\d+), (\\d+)\\), Item: (.+?),(?: Container: (.+?),)? Location: X=(-?\\d+\\.\\d+) Y=(-?\\d+\\.\\d+) Z=(-?\\d+\\.\\d+), Distance: ([\\d.]+) m");
            Pattern ammoCountViolationPattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): Ammo count violation detected for user -> Weapon: (.+?), User: (.+?) \\((\\d+), (\\d+)\\), Location: X=(-?\\d+\\.\\d+) Y=(-?\\d+\\.\\d+) Z=(-?\\d+\\.\\d+)");
            Pattern lightItemInteractViolationDetectedPattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): Light item interact violation detected -> (\\w+), Item: (.+?), User: ([^,]+) \\((\\d+), (\\d+)\\) Location: X=(-?\\d+\\.\\d+) Y=(-?\\d+\\.\\d+) Z=(-?\\d+\\.\\d+), Container: ([^,]+), Location: X=(-?\\d+\\.\\d+) Y=(-?\\d+\\.\\d+) Z=(-?\\d+\\.\\d+), Distance: ([\\d.]+) m");
            Pattern addItemInventoryViolationDetectedPattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): Add item to inventory violation detected -> (\\w+), Item: (.+?), User: ([^,]+) \\((\\d+), (\\d+)\\) ,(?: Items container: (.+?),)? Location: X=(-?\\d+\\.\\d+) Y=(-?\\d+\\.\\d+) Z=(-?\\d+\\.\\d+), Distance: ([\\d.]+) m");
            Pattern ammoCountViolation2Pattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): Total violations detected for user -> User: (.+?) \\((\\d+), (\\d+)\\), Type: (.+?), Count: (\\d+)");
            Pattern violationPattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): Take damage violation detected -> Attacker: (.+?) \\((\\d+), (\\d+)\\), Victim: (.+?) \\((\\d+), (\\d+)\\) Weapon: (.+?) \\[Projectile\\] S\\[AttackerLoc : (-?\\d+\\.\\d+), (-?\\d+\\.\\d+), (-?\\d+\\.\\d+) VictimLoc: (-?\\d+\\.\\d+), (-?\\d+\\.\\d+), (-?\\d+\\.\\d+)\\] C\\[AttackerLoc: (-?\\d+\\.\\d+), (-?\\d+\\.\\d+), (-?\\d+\\.\\d+), VictimLoc: (-?\\d+\\.\\d+), (-?\\d+\\.\\d+), (-?\\d+\\.\\d+)\\], Attacker location distance: (\\d+\\.\\d+) m, Victim location distance: (\\d+\\.\\d+) m");
            Pattern throwItemViolationPattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): Throw item violation detected -> Attemp to throw item that no prisoner has in hands: (.+?)");
            Pattern disappearancePattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): \\[Disappeared\\] (.+?)\\. VehicleId: (\\d+)\\. Owner: (\\d+ \\(\\d+, .+?\\)|N/A)\\. Location: X=([\\d.-]+) Y=([\\d.-]+) Z=([\\d.-]+)");
            Pattern destructionPattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): \\[Destroyed\\] (.+?)\\. VehicleId: (\\d+)\\. Owner: (\\d+) \\((\\d+), (.+?)\\)\\. Location: X=([\\d.-]+) Y=([\\d.-]+) Z=([\\d.-]+)");
            Pattern takeBudingPattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}):.*?Attacker: (.*?) \\((\\d+), (\\d+)\\), Weapon: (.*?) \\[Projectile\\] S\\[Location: (-?\\d+\\.\\d+), (-?\\d+\\.\\d+), (-?\\d+\\.\\d+)\\] C\\[Location: (-?\\d+\\.\\d+), (-?\\d+\\.\\d+), (-?\\d+\\.\\d+)\\], Distance: (\\d+\\.\\d+) m");
            Pattern removeTrapPattern = Pattern.compile("(\\d{4}\\.\\d{2}\\.\\d{2}-\\d{2}\\.\\d{2}\\.\\d{2}): Take damage to base building element violation detected -> Attacker: ([\\w\\d]+) \\((\\d+), (\\d+)\\), Weapon: ([\\w_]+) \\[Projectile\\] S\\[Location: ([\\d.-]+), ([\\d.-]+), ([\\d.-]+)\\] C\\[Location: ([\\d.-]+), ([\\d.-]+), ([\\d.-]+)\\], Distance: ([\\d.]+) m");
            List<ServerFTPLogViolation> logViolations = Lists.newArrayList();

            for (GameLogLine line : splitLine(ftpQueueItem)) {
                String lineContext = line.getLineContext();
                if (lineContext.length() < 5 || lineContext.endsWith("}") || lineContext.endsWith("{")) {
                    continue;
                }
                Matcher aConZGameModeKickPlayerPatternMatcher = aConZGameModeKickPlayerPattern.matcher(lineContext);
                Matcher banByUserIdMatcher = banByUserId.matcher(lineContext);
                Matcher requestCharacterActionViolationDetectedPatternMatcher = requestCharacterActionViolationDetectedPattern.matcher(lineContext);
                Matcher outOfInteractionRangeMatcher = outOfInteractionRangePattern.matcher(lineContext);
                Matcher ammoCountViolationMatcher = ammoCountViolationPattern.matcher(lineContext);
                Matcher ammoCountViolation2Matcher = ammoCountViolation2Pattern.matcher(lineContext);
                Matcher lightItemInteractViolationDetectedMatcher = lightItemInteractViolationDetectedPattern.matcher(lineContext);
                Matcher addItemInventoryViolationDetectedMatcher = addItemInventoryViolationDetectedPattern.matcher(lineContext);
                Matcher violationMatcher = violationPattern.matcher(lineContext);
                Matcher throwItemViolationMatcher = throwItemViolationPattern.matcher(lineContext);
                Matcher disappearancMatcher = disappearancePattern.matcher(lineContext);
                Matcher destructionMatcher = destructionPattern.matcher(lineContext);
                Matcher takeBudingPatternMatcher = takeBudingPattern.matcher(lineContext);
                Matcher removeTrapPatternMatcher = removeTrapPattern.matcher(lineContext);

                ServerFTPLogViolation violation = new ServerFTPLogViolation();
                violation.setId(snowflakeIdGenerator.nextId());
                violation.setFileId(ftpQueueItem.getFileId());
                violation.setServerId(ftpQueueItem.getServer().getId());
                violation.setLineStart(line.getStartByte());
                violation.setLineEnd(line.getEndByte());
                violation.setCreateTime(LocalDateTime.now());
                //1.T出用户 2用户行为违规 3衣物超出交互范围违规 4数值不匹配 5轻型物品超出交互范围违规/没有权限 6将物品添加到容器内违规 7击杀违规 8没有在手中的物品投掷 9载具消失 10 载具被摧毁 11.ban出用户
                // 12建筑被破坏 13 非法拆除陷阱
                if (aConZGameModeKickPlayerPatternMatcher.find()) {
                    violation.setType(1);
                    violation.setServerTime(parseTimestamp(aConZGameModeKickPlayerPatternMatcher.group(1), ftpQueueItem));
                    assembleViolationPlayer(aConZGameModeKickPlayerPatternMatcher.group(2), violation);
                    if (aConZGameModeKickPlayerPatternMatcher.group(3).contains("NetErrorUnauthorized")) {
                        violation.setConvert("踢出原因：网络授权错误");
                    } else if (aConZGameModeKickPlayerPatternMatcher.group(3).contains("GenericKickReason")) {
                        violation.setConvert("踢出原因：一般原因：日志未标出");
                    } else if (aConZGameModeKickPlayerPatternMatcher.group(3).contains("NetErrorPingTooHigh")) {
                        violation.setConvert("踢出原因：网络延迟过高");
                    } else if (aConZGameModeKickPlayerPatternMatcher.group(3).contains("[Auto Add] Violation detected")) {
                        violation.setConvert("踢出原因：一般原因：[自动添加]检测到违规");
                    } else if (aConZGameModeKickPlayerPatternMatcher.group(3).contains("Request character action violation")) {
                        violation.setConvert("踢出原因：可能是由于玩家执行了违规操作");
                    } else if (aConZGameModeKickPlayerPatternMatcher.group(3).contains("Add item to inventory violation")) {
                        violation.setConvert("踢出原因：检测到违规：玩家试图向自己的物品栏添加物品");
                    } else if (aConZGameModeKickPlayerPatternMatcher.group(3).contains("Damage to player violation")) {
                        violation.setConvert("踢出原因：玩家造成了对其他玩家的伤害违规");
                    } else if (aConZGameModeKickPlayerPatternMatcher.group(3).contains("Infinite ammo cheat detected")) {
                        violation.setConvert("踢出原因：弹药数量不匹配/无限弹药");
                    } else {
                        violation.setConvert("踢出原因：未知");
                    }
                } else if (requestCharacterActionViolationDetectedPatternMatcher.find()) {
                    violation.setType(2);
                    violation.setServerTime(parseTimestamp(requestCharacterActionViolationDetectedPatternMatcher.group(1), ftpQueueItem));
                    String desc = requestCharacterActionViolationDetectedPatternMatcher.group(5);
                    String action = requestCharacterActionViolationDetectedPatternMatcher.group(6);
                    String itemID = desc.replace(action + "Description_", "");
                    violation.setConvert("用户违规行为： " + getViolationActionCnName(action) + " ID： " + itemID + " " +
                            "服务器坐标：" + requestCharacterActionViolationDetectedPatternMatcher.group(7) + " " + requestCharacterActionViolationDetectedPatternMatcher.group(8) + " " + requestCharacterActionViolationDetectedPatternMatcher.group(9) +
                            " 客户端坐标：" + requestCharacterActionViolationDetectedPatternMatcher.group(10) + " " + requestCharacterActionViolationDetectedPatternMatcher.group(11) + " " + requestCharacterActionViolationDetectedPatternMatcher.group(12) +
                            " 距离：" + requestCharacterActionViolationDetectedPatternMatcher.group(13) + "米");
                    assembleViolationPlayer(requestCharacterActionViolationDetectedPatternMatcher.group(4), violation);
                } else if (banByUserIdMatcher.find()) {
                    violation.setType(11);
                    violation.setServerTime(parseTimestamp(banByUserIdMatcher.group(1), ftpQueueItem));
                    assembleViolationPlayer(banByUserIdMatcher.group(2), violation);
                    violation.setConvert("BanPlayerById");
                } else if (outOfInteractionRangeMatcher.find()) {
                    violation.setType(3);
                    violation.setServerTime(parseTimestamp(outOfInteractionRangeMatcher.group(1), ftpQueueItem));
                    assembleViolationPlayer(outOfInteractionRangeMatcher.group(5), violation);
                    String item = outOfInteractionRangeMatcher.group(6);
                    String[] splitItem = item.split("_C_");
                    String itemName = item;
                    String itemId = item;
                    if (splitItem.length == 2) {
                        itemName = getSpawnItemCodeCnName(splitItem[0]);
                        itemId = splitItem[1];
                    }
                    String container = outOfInteractionRangeMatcher.group(7);
                    String appendContainerStr = "";
                    if (StringUtils.isNotBlank(container)) {
                        String[] splitContainer = container.split("_C_");
                        if (splitContainer.length == 2) {
                            appendContainerStr = "容器名称：" + getSpawnItemCodeCnName(splitContainer[0]) + " ID:" + splitContainer[1] + " ";
                        }
                    }
                    String distance = outOfInteractionRangeMatcher.group(11);
                    violation.setConvert("用户违规行为: 超出交互范围 物品名称：" + itemName + " ID:" + itemId + " " + appendContainerStr + " " +
                            "坐标：" + outOfInteractionRangeMatcher.group(8) + " " + outOfInteractionRangeMatcher.group(9) + " " + outOfInteractionRangeMatcher.group(10) + " 距离：" + distance + "米");
                } else if (ammoCountViolationMatcher.find()) {
                    violation.setType(4);
                    violation.setServerTime(parseTimestamp(ammoCountViolationMatcher.group(1), ftpQueueItem));
                    assembleViolationPlayer(ammoCountViolationMatcher.group(5), violation);
                    String weapon = ammoCountViolationMatcher.group(2).trim();
                    String weaponName = weapon;
                    String weaponId = weapon;
                    String[] splitWeapon = weapon.split("_C_");
                    if (splitWeapon.length == 2) {
                        weaponName = getSpawnItemCodeCnName(splitWeapon[0]);
                        weaponId = splitWeapon[1];

                    }
                    violation.setConvert("用户违规行为： 弹药数量不一致 武器名称：" + weaponName + " ID：" + weaponId + " 坐标：" + ammoCountViolationMatcher.group(6) + " " + ammoCountViolationMatcher.group(7) + " " + ammoCountViolationMatcher.group(8) + "");

                } else if (ammoCountViolation2Matcher.find()) {
                    violation.setType(4);
                    violation.setServerTime(parseTimestamp(ammoCountViolation2Matcher.group(1), ftpQueueItem));
                    assembleViolationPlayer(ammoCountViolation2Matcher.group(4), violation);
                    String action = ammoCountViolation2Matcher.group(5).trim();
                    String actionCn = getViolationActionCnName(action);
                    violation.setConvert("用户违规行为：" + actionCn + " 数量 " + ammoCountViolation2Matcher.group(6));
                } else if (lightItemInteractViolationDetectedMatcher.find()) {
                    violation.setType(5);
                    violation.setServerTime(parseTimestamp(lightItemInteractViolationDetectedMatcher.group(1), ftpQueueItem));
                    assembleViolationPlayer(lightItemInteractViolationDetectedMatcher.group(6), violation);

                    String item = lightItemInteractViolationDetectedMatcher.group(3);
                    String itemName;
                    if (item.contains("_C_")) {
                        itemName = getSpawnItemCodeCnName(item.split("_C_")[0]);
                    } else {
                        itemName = getSpawnItemCodeCnName(item.replace("_C", ""));
                    }
                    String appendStr = "";
                    String container = lightItemInteractViolationDetectedMatcher.group(10);
                    String[] splitContainer = container.split("_C_");
                    if (splitContainer.length == 2) {
                        appendStr = "容器名称：" + getSpawnItemCodeCnName(splitContainer[0]) + " ID：" + splitContainer[1];
                    }

                    String action = lightItemInteractViolationDetectedMatcher.group(2).trim();
                    String actionCn = getViolationActionCnName(action);
                    violation.setConvert("用户违规行为： " + actionCn + " 物品名称：" + itemName +
                            " 用户坐标：" + lightItemInteractViolationDetectedMatcher.group(7) + " " + lightItemInteractViolationDetectedMatcher.group(8) + " " + lightItemInteractViolationDetectedMatcher.group(9) + " " + appendStr +
                            " 容器坐标：" + lightItemInteractViolationDetectedMatcher.group(11) + " " + lightItemInteractViolationDetectedMatcher.group(12) + " " + lightItemInteractViolationDetectedMatcher.group(13) + " " +
                            "距离：" + lightItemInteractViolationDetectedMatcher.group(14) + "米");
                } else if (addItemInventoryViolationDetectedMatcher.find()) {
                    violation.setType(6);
                    violation.setServerTime(parseTimestamp(addItemInventoryViolationDetectedMatcher.group(1), ftpQueueItem));
                    assembleViolationPlayer(addItemInventoryViolationDetectedMatcher.group(6), violation);
                    String action = addItemInventoryViolationDetectedMatcher.group(2).trim();
                    String actionCn = getViolationActionCnName(action);
                    String item = addItemInventoryViolationDetectedMatcher.group(3);
                    String itemName = item;
                    String itemId = item;
                    if (item.contains("_C_")) {
                        String[] split = item.split("_C_");
                        if (split.length == 2) {
                            itemName = getSpawnItemCodeCnName(split[0]);
                            itemId = split[1];
                        }
                    } else {
                        itemName = getSpawnItemCodeCnName(item.replace("_C", ""));
                    }

                    StringBuilder stringBuilder = new StringBuilder();
                    stringBuilder.append("用户违规行为：").append(actionCn).append(" 物品名称：").append(itemName).append(" ");
                    if (StringUtils.isNotBlank(itemId)) {
                        stringBuilder.append("ID：").append(itemId).append(" ");

                    }
                    String container = addItemInventoryViolationDetectedMatcher.group(7);
                    if (StringUtils.isNotBlank(container)) {
                        String[] splitContainer = container.split("_C_");
                        stringBuilder.append("容器名称：").append(getSpawnItemCodeCnName(splitContainer[0])).append(" ID：").append(splitContainer[1]).append(" ");
                    }
                    stringBuilder.append("坐标：").append(addItemInventoryViolationDetectedMatcher.group(8))
                            .append(" ").append(addItemInventoryViolationDetectedMatcher.group(9))
                            .append(" ").append(addItemInventoryViolationDetectedMatcher.group(10))
                            .append(" 距离：").append(addItemInventoryViolationDetectedMatcher.group(11)).append("米");


                    violation.setConvert(stringBuilder.toString());
                } else if (violationMatcher.find()) {
                    violation.setType(7);
                    violation.setServerTime(parseTimestamp(violationMatcher.group(1), ftpQueueItem));
                    assembleViolationPlayer(violationMatcher.group(4), violation);
                    String weaponName = getSpawnItemCodeCnName(violationMatcher.group(8).trim().split("_C")[0]);
                    violation.setConvert("受害者：" + violationMatcher.group(5) + " " +
                            "c_攻击者坐标：" + violationMatcher.group(15) + ", " + violationMatcher.group(16) + ", " + violationMatcher.group(17) + " " +
                            "c_受害者坐标 " + violationMatcher.group(18) + ", " + violationMatcher.group(19) + ", " + violationMatcher.group(20) + " " +
                            "s_攻击者坐标：" + violationMatcher.group(9) + ", " + violationMatcher.group(10) + ", " + violationMatcher.group(11) + " " +
                            "s_受害者坐标 " + violationMatcher.group(12) + ", " + violationMatcher.group(13) + ", " + violationMatcher.group(14) + " " +
                            "武器 " + weaponName + " 攻击者距离" + violationMatcher.group(21) + " 受害者距离" + violationMatcher.group(22) + "");
                } else if (throwItemViolationMatcher.find()) {
                    violation.setType(8);
                    violation.setServerTime(parseTimestamp(throwItemViolationMatcher.group(1), ftpQueueItem));
                    String item = throwItemViolationMatcher.group(2);
                    String itemName = item;
                    String itemId = item;
                    if (item.contains("_C_")) {
                        String[] split = item.split("_C_");
                        if (split.length == 2) {
                            itemName = getSpawnItemCodeCnName(split[0]);
                            itemId = split[1];
                        }
                    } else {
                        itemName = getSpawnItemCodeCnName(item.replace("_C", ""));
                    }
                    violation.setConvert("尝试投掷出一个" + itemName + " ID" + itemId + " （日志无标注归属用户）");
                } else if (disappearancMatcher.find()) {
                    violation.setType(9);
                    String steamId = disappearancMatcher.group(4);
                    if (steamId.length() > 17) {
                        assembleViolationPlayer(steamId.trim().substring(0, 17), violation);
                    }
                    violation.setServerTime(parseTimestamp(disappearancMatcher.group(1), ftpQueueItem));
                    violation.setConvert("载具名称" + disappearancMatcher.group(2) + " ID" + disappearancMatcher.group(3) + " 坐标" + disappearancMatcher.group(5) + "," + disappearancMatcher.group(6) + "," + disappearancMatcher.group(7));
                } else if (destructionMatcher.find()) {
                    violation.setType(10);
                    assembleViolationPlayer(destructionMatcher.group(4), violation);
                    violation.setServerTime(parseTimestamp(destructionMatcher.group(1), ftpQueueItem));
                    violation.setConvert("载具名称" + destructionMatcher.group(2) + " ID" + destructionMatcher.group(3) + " 坐标" + destructionMatcher.group(7) + "," + destructionMatcher.group(8) + "," + destructionMatcher.group(9));
                } else if (takeBudingPatternMatcher.find()) {
                    StringBuilder builder = new StringBuilder();
                    violation.setType(12);
                    violation.setServerTime(parseTimestamp(takeBudingPatternMatcher.group(1), ftpQueueItem));
                    assembleViolationPlayer(takeBudingPatternMatcher.group(4), violation);

                    String cnName = getSpawnItemCodeCnName(takeBudingPatternMatcher.group(5));
                    builder.append("武器:").append(cnName).append(" ")
                            .append("开始坐标：").append(" ").append(takeBudingPatternMatcher.group(6)).append(" ").append(takeBudingPatternMatcher.group(7)).append(" ").append(takeBudingPatternMatcher.group(8))
                            .append("目标坐标：").append(" ").append(takeBudingPatternMatcher.group(9)).append(" ").append(takeBudingPatternMatcher.group(10)).append(" ").append(takeBudingPatternMatcher.group(11))
                            .append("距离：").append(takeBudingPatternMatcher.group(12)).append("米");
                    violation.setConvert(builder.toString());
                } else if (removeTrapPatternMatcher.find()) {
                    StringBuilder builder = new StringBuilder();
                    violation.setType(13);
                    violation.setServerTime(parseTimestamp(removeTrapPatternMatcher.group(1), ftpQueueItem));
                    assembleViolationPlayer(removeTrapPatternMatcher.group(4), violation);
                    String wCnName = getSpawnItemCodeCnName(removeTrapPatternMatcher.group(5));
                    String tCnName = getSpawnItemCodeCnName(removeTrapPatternMatcher.group(2));
                    builder.append("武器:").append(wCnName).append(" ")
                            .append("陷阱:").append(tCnName).append(" ")
                            .append("服务器坐标：").append(" ").append(removeTrapPatternMatcher.group(6)).append(" ").append(removeTrapPatternMatcher.group(7)).append(" ").append(removeTrapPatternMatcher.group(8))
                            .append("客户端坐标：").append(" ").append(removeTrapPatternMatcher.group(9)).append(" ").append(removeTrapPatternMatcher.group(10)).append(" ").append(removeTrapPatternMatcher.group(11))
                            .append("距离：").append(removeTrapPatternMatcher.group(12)).append("米");
                    violation.setConvert(builder.toString());
                } else if (lineContext.contains("is disarming traps illegally without a character action")) {
                    violation.setType(13);
                    violation.setConvert(lineContext);
                } else {
                    violation.setType(99);
                    violation.setServerTime(LocalDateTime.now());
                    violation.setConvert(lineContext);
                    continue;
                }
                logViolations.add(violation);
            }
            logViolations.forEach(serverFTPLogViolationMapper::insert);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    private void assembleViolationPlayer(String steamId, ServerFTPLogViolation violation) {
        Player player = PLAYER_CACHE.getIfPresent(Long.parseLong(steamId));
        if (player == null) {
            player = getOrInsertPlayerServer(Long.parseLong(steamId), violation.getServerId(), Strings.EMPTY);
        }
        violation.setPlayerId(player.getId());
        violation.setPlayerSteamId(player.getSteamId());
    }


    private String getViolationActionCnName(String action) {
        String cnName = ACTION_CN_NAMES.get(action.trim());
        return StringUtils.isNotBlank(cnName) ? cnName : action;
    }

}
